/**
 * Created by seeker910 on 2014/8/22.
 *  @description ListView 是以展示控件集合的组件。纯数据类型仅支持字符串集合展示
 */
Rsd.define('Rsd.control.List', {
    extend: 'Rsd.control.Component',
    requires: ['Rsd.form.Label'],
    xtype: 'list',
    ctrlTagName: 'ol',
    cls: 'x-list',
    preventDefault:false,
    readonly: false,
    /**
    * @description 键值字段名
     * */
    itemKeyMember: 'id',
    /**
     * 元素 默认类型
     */
    itemXtype: null,
    /**
     * {
     *      target:'li' //'li' or 'item'
     *      click:null,
     *      dblClick:null
     * }
     */
    //itemClick: null,
    //itemDblClick: '',
    //itemCheckedchange:'',
    /**
     *  单击时选中
     */
    selectedOnClick: true,
    /**
     *  双击击时选中
     */
    selectedOnDblClick: true,
    /**
     * 显示 勾选框
     */
    showCheckbox:false,
    /*
    * */
    itemSelectedCls: '',
    /**
    * @description item  默认样式 ,即dom li 样式
    * */
    //itemStyle: {height: '30px', lineHeight: '30px',float:'left'},
    /**
     * dom li class
     */
    itemCls: null,
    /**
     * dom li 拖动设置
     */
    //itemDrag:{},
    /*
    * 启用hover样式，并指定样式名称，null,'',false 表示不启用
    * */
    usingItemHover: false,
    /**
     *
     * @description items 布局方式 ，valueof: none,vbox,hbox
     * {
     *      type:'hbox',
     *      align:'left',
     * }
     * */
    //layout:'hbox',
    /**
     * 启用流式布局,display设置为flex,效果为高度或宽度益处时自动换行
     */
    wrap:true,
    /**
     * list li 节点
     */
    liNodes:[],
    liButtons:null,
    liStyle:null,
    /**
     * item控件
     */
    //items:[], 
    /**
     * list 子元素 ，支持 flex 属性，设置后会被应用到li 节点上
     */
    dataSource: [], 
    /*
     none:不使用项目符号
     disc:实心圆，默认值
     circle:空心圆
     square:实心方块
     decimal:阿拉伯数字
     lower-roman:小写罗马数字
     upper-roman:大写罗马数字
     lower-alpha:小写英文字母
     upper-alpha:大写英文字母
     */
    listType: 'none',
    /*
    * */
    label: { position: 'top', align: 'center', height: 40 }, 
    /*
    *
    * */
    constructor: function List(config) {
        config = config || {}; 
        this.apply(config); 
        if(config.items && config.items.length > 0)
        {
            console.error('禁止使用items,请使用dataSource代替',config);  
        }
        this.liNodes = [];
    },
    /**
     * 
     */
    initComponentEx: function initComponentEx() {
        this.callParent();
        var _style = {
            listStyleType:this.listType,
            margin:'0xp',
        }
        //布局处理 
        //console.log(this.layout.type);
        { 
            switch(this.layout.type)
            {
                case 'none':
                    {
                        //不使用flex
                        _style.display = 'inline-block';
                        break;
                    }
                case 'vbox':
                    {
                        _style.display = 'flex'; 
                        _style.flexFlow = this.wrap ? 'column wrap' : 'column nowrap';
                        break;
                    }
                case 'hbox':
                    {
                        _style.display = 'flex';
                        _style.flexFlow =  this.wrap ? 'row wrap' : 'row nowrap'; 
                        break;
                    }
            } 
            //弹性布局 

            //align-content: [控制整体][仅多行]控制的是flex容器内多行之间的对齐方式，决定了行与行之间在交叉轴方向上的空白区域如何分配。
            //               只在多行情况下有效(内只有一行时，该属性不起作用)，多行元素会[整体居中]。
            //可选值包括：
            // stretch(默认，拉伸以填满整个交叉轴空间)、
            // flex-start、
            // flex-end、
            // center、
            // space-between、
            // space-around

            //justifyContent:[控制单个项目][单行和多行] 定义了flex项目或grid项目在主轴（main axis）上的对齐方式，即项目在一行内的水平或垂直分布方式。
            //可选值包括：
            // flex-start(默认，左对齐或顶部对齐)、
            // flex-end(右对齐或底部对齐)、
            // center(居中对齐)、
            // space-between(两端对齐，项目之间的间隔相等)、
            // space-around(每个项目两侧的间隔相等)、
            // space-evenly(所有项目之间的间距相等)。
 

            //alignItems:[控制单个项目][单行和多行]定义了flex项目或grid项目在交叉轴（cross axis）上的对齐方式，即项目的垂直对齐方式（当主轴是横向时）或者水平对齐方式（当主轴是纵向时）
            //可选值包括：
            // stretch(默认，拉伸以填满整个交叉轴空间)、
            // flex-start(交叉轴起点对齐)、
            // flex-end(交叉轴终点对齐)、
            // center(交叉轴居中对齐)等。
 
            //justify-items：在弹性（flex）布局中没有效果，该属性会被忽略。

            switch(this.layout.align)
            {
                case 'top': 
                    if(this.layout.type =='hbox')
                    {
                        //无效
                    }
                    if(this.layout.type =='vbox')
                    {
                        _style.alignItems = 'flex-start'; //[单行和多行]
                    } 
                    break;
                case 'bottom': 
                    if(this.layout.type =='hbox')
                    { 
                        //无效
                    }
                    if(this.layout.type =='vbox')
                    {
                        _style.alignItems = 'flex-end'; //[单行和多行]
                    } 
                    break;
                case 'left':
                     
                     if(this.layout.type =='hbox')
                     { 
                        if(this.wrap)
                        {
                             _style.alignContent = 'start';//[整体，仅多行]仅在Flex布局中，且只针对多行的情况（即flex-wrap: wrap时）有效
                        }
                        else
                        {
                             _style.justifyContent = 'start';//[子项目，单行和多行]
                        } 
                     }
                     if(this.layout.type =='vbox')
                     {
                        //无效
                     } 
                    break;
                case 'right': 
                     if(this.layout.type =='hbox')
                     { 
                         if(this.wrap)
                         {
                            _style.alignContent = 'end';//[整体，仅多行]
                         }
                         else
                         {
                            _style.justifyContent = 'end';//[子项目，单行和多行]
                         }
                        
                     }
                     if(this.layout.type =='vbox')
                     {
                         //无效
                     } 
                    break;
                case 'center':
                default: 
                    if(this.layout.type =='hbox')
                    {
                        _style.alignItems = 'center';
                    }
                    if(this.layout.type =='vbox')
                    {
                        _style.justifyContent = 'center';
                    } 
                    break;

            }
        }

        this.setElStyle(this.ctrl.element,_style);
    
        this.setElAttribute('dom', 'layout', this.layout.type);

        var me = this;
        //以下事件为拖动过程对象事件，与被拖动对象无关，所以不受是否允许拖动（属性：me.itemDrag.value）限制   
        if(!Rsd.isEmpty(me.itemDrag.target))//指定目标对象
        {
            var target = me.itemDrag.target;
            if(Rsd.isString(target))
            {
                switch(target)
                {
                    case 'dom':
                        target = me.dom;
                        break;
                    case 'label':
                        target = me.label.element;
                        break;
                    case 'ctrl':
                        target = me.ctrl.element;
                        break;
                    case 'item':
                        target = null;
                        //在添加item 时注册
                        break;
                    default:
                        target = document.getElementById(target);
                        break;
                }
                
            }
            if(target)
            { 
                //在拖动元素进入目标元素时触发，通常用于设置拖动时的样式
                if (me.itemDrag.onDragEnter) 
                {
                    Rsd.onDragEnter(target,me.id + me.itemDrag.onDragEnter,function (e) {
                        //console.log('onDragEnter',e.target.id,target); 
                        //此事件中 不允许 获得dataTransfer数据 
                        //me.funApplyByIOC(me.itemDrag.onDragEnter, [target, e]);
                    });
                }
                //在拖动元素在目标元素上方悬停时触发，通常用于防止默认的拖放行为
                if (me.itemDrag.onDragOver) 
                {
                    Rsd.onDragOver(target,me.id + me.itemDrag.onDragOver, function (e) {
                        //console.log('onDragOver',e.target.id,target); 
                        //此事件中 不允许 获得dataTransfer数据 
                        //me.funApplyByIOC(me.itemDrag.onDragOver, [target, e]);
                    });
                }
                //在拖动元素离开目标元素时触发，通常用于设置拖动时的样式
                if (me.itemDrag.onDragLeave) 
                {
                    Rsd.onDragLeave(target, me.id + me.itemDrag.onDragLeave,function (e) {
                        //console.log('onDragLeave',e.target.id,target,e.dataTransfer.getData('text/plain')); 
                        //此事件中 不允许 获得dataTransfer数据 
                        //me.funApplyByIOC(me.itemDrag.onDragLeave, [target,e]);
                    });
                }
            }
            
        }
 
    },
    
    /**
     *@description control控件加载数据 无回调
      @param {Array} data 数据源 
      @param {Array} callback  回调函数 
     * */
    loadData: function loadData(data, callback) {
 
        //this.log('list loadData');
        if (this.dataSource == data) {
            //return;
        }
        this.dataSource = data || this.dataSource;

        //this.log(this.dataSource); 

        if(!this.dataSource)
        {
             return this;
        }
        
        if(!Rsd.isArray(this.dataSource))
        {
            console.error('Rsd.control.List.loadData()方法的data参数必须是数组', this.dataSource);
            return this;
        }
        
        //console.log(this.dataSource);
        this.removeAll();

        for (var i in this.dataSource) {
 
            var _item = this.newItem(this.dataSource[i], i); 
            //
            this.ctrl.element.appendChild(_item.element);
            //items 只存储控件对象
            this.items.push(_item.innerCtrl);
            if (_item.innerCtrl.loadData) {
                try
                {
                    _item.innerCtrl.loadData();
                }
                catch(err)
                {
                    this.error(err);
                }
                
            }
        }

        Rsd.callFunction(this, callback, [this.dataSource]);
 
        return this;
    },
    /**
     * @description 向列表中追加一个元素
     */
    addItem:function addItem(config)
    {
        var _item = this.newItem(config);
        //
        this.ctrl.element.appendChild(_item.element);
        //items 只存储控件对象
        this.items.push(_item.innerCtrl);
        //加载数据
        if(_item.innerCtrl.loadData)
        {
            _item.innerCtrl.loadData();
        }

    },
    /**
     * @param {*} index 
     * @param {*} config 
     */
    insertItem:function insertItem(index,config)
    {
        var _item = this.newItem(config);
        //
        var indexChild = this.ctrl.element.childNodes[index];
        //console.log(index,indexChild);
        this.ctrl.element.insertBefore(_item.element,indexChild);
        //items 只存储控件对象
        this.items.splice(index,0,_item.innerCtrl);
         if(_item.innerCtrl.loadData)
        {
            _item.innerCtrl.loadData();
        }
    },
    /**
     * @description  清空列表
     *  */
    removeAll: function removeAll() {

        if (this.ctrl.element) {
            this.ctrl.element.innerHTML = "";
        }
        this.items = [];
        this.liNodes = [];
    },
    /**
     * 
     * @param {*} key 
     */
    findItem:function findItem(key)
    {

    },
    /**
    * @param key {int|string} int type is index value,string type is key value.
    * @param scrollIntoView
    * */
    select: function select(key, scrollIntoView) {

        if (!this.ctrl.element) {
            return;
        }

        if (Rsd.isString(key)) {
            var express = '[id=' + key + ']';
            var list = Rsd.select(this.ctrl.element,express);
            //console.log(this.ctrl.element.querySelectorAll(express),express);
            if (list.length > 0) {
                list[0].click();
                if(scrollIntoView)
                {
                    list[0].scrollIntoView();
                }
            }
            return this;
        }
        //-1:清除所有选择
        if (Rsd.isNumber(key) && key < 0) {

            var list = this.ctrl.element.querySelectorAll('.' + this.itemSelectedCls);
            //console.trace('removeCls',list);
            for (var i in list) {
                this.removeCls(list[i], this.itemSelectedCls);
            }
            return this;
        }
        //按索引
        if (Rsd.isNumber(key) && key < this.items.length) {
            var _index = key % this.items.length;
            this.liNodes[_index].click(); 
            //console.log(this.liNodes[_index]);
            if(scrollIntoView)
            {
                this.liNodes[_index].scrollIntoView();
            }
            return this;
        }

        return this;
    },
    /**
     * 
     * @description 选中节点滚动到可视区
     * @param {*} key
     * @param {*} boolean
     * ‌behavior‌：定义滚动行为，可选 auto（默认，跳跃式滚动）、smooth（平滑滚动）。 ‌ 
     * block‌：垂直对齐方式，可选 start（顶部对齐）、center、end（底部对齐）、nearest（最近位置）。 ‌ 
     * inline‌：水平对齐方式，可选 start、center、end、nearest。 ‌  
     * alignToTop‌：布尔值参数，true 对应 {block: "start", inline: "nearest"}，false 对应 {block: "end", inline: "nearest"}
     * */
    scrollCurrentIntoView: function scrollCurrentIntoView(key, top) {
        var dom = document.getElementById(key);
        if (dom) {
            dom.scrollIntoView({'behavior‌':'smooth','alignToTop‌':top});
        }
    },
    
    /**
     * @private 
     * @description 创建一个新的列表项 li ,但是没有添加 ctrl.element中
     * @param {*} 
     * @param {*} index 对象所在数组 索引
     * @returns 返回item对象，item.element是li dom,item.innerCtrl 是li内部子节点,dataSource是innerCtrl config
     */
    newItem: function newItem(config,index) {
 
        var me = this;
        var _config = config || {};//item 是 li节点，item.innerCtrl 是li内部子节点
        
        if (Rsd.isString(config)) {

            _config = {
                innerCtrl:config//仅字符串，将作为一个TextContent处理
            };
        }  
        //this.log(config); 
       
        //
        var li = document.createElement('li');  ;
        var innerCtrl = me.createInnerControl(_config);
        var evtTarget = li;
        //li 节点
        me.liNodes.push(li);  
         
        //取消 flex ，可以使用 liStyle: {flex:1}代替
        // var flex = 0;
        // if (_config.flex) {

        //     flex = _config['flex'];
        //     delete _config['flex'];
        // }
        // if (flex) {
        //     li.style.flex = flex;
        // }

        li.style.display = 'flex';
        li.style.position = 'relative';

        if (!_config.key && Rsd.isObject(_config)) {
            _config.key =  _config[me.itemKeyMember] || index;
        }
        if (_config.key) {
            li.setAttribute('id', _config.key);
        }
        else
        {
            li.setAttribute('id', index);
        }
        //子元素 统一样式
        if (me.itemStyle) { 
            var sizeUnit = me.sizeUnit || 'px';
            Rsd.setElStyle(li, me.itemStyle, sizeUnit); 
        }  
        //子元素 单个 li dom style
        if (_config.liStyle) {
            var sizeUnit = me.sizeUnit || 'px';
            Rsd.setElStyle(li, _config.liStyle, sizeUnit);
        } 
        
        if (me.usingItemHover && _config.usingHover !== false) {

            li.classList.add(me.usingItemHover===true?'x-li-hover':me.usingItemHover);
        }
        //  
        //me.log('innerCtrl',Rsd.getType(_config.innerCtrl));
        if(Rsd.isString(innerCtrl))
        { 
            li.appendChild(document.createTextNode(innerCtrl)); 
            li.style.alignSelf = 'center';
        }
        if(innerCtrl instanceof HTMLElement)
        {
            //me.log('HTMLElement');
            li.appendChild(innerCtrl); 
            //li.style.display = 'flex';
            li.style.alignSelf = 'center';
            if(me.itemClick.target == 'item')
            {
                evtTarget = innerCtrl;
            }
            
        }
        if(innerCtrl instanceof Rsd.common.ComponentX)
        {
             //me.log('Rsd.common.ComponentX'); 
            innerCtrl.parent = me;
            innerCtrl.style.alignSelf = 'center';
            innerCtrl.renderTo(li).doLayout();
            //_config.content = innerCtrl;
            if(me.itemClick.target == 'item')
            {
                evtTarget = innerCtrl.dom;
            }  
        }
        //按钮 
        var _buttons = _config.liButtons || this.buttons|| {};
         
        if(!Rsd.isEmpty(_buttons))
        {
            var _panel = document.createElement('div');
            _panel.id= _config.key + 'btn_panel'
            _panel.style.position = 'absolute';
            _panel.style.zIndex = 999;
            _panel.style.borderRadius = '5px';
            _panel.style.display = 'flex';
            _panel.style.alignItems = 'center';
            _panel.style.justifyContent = 'center';

            _panel.style.lineHeight = '40px';
            _panel.style.backgroundColor = '#58636c52';
           
            switch(_buttons.position)
            {
                 case 'top':
                    {
                        _panel.style.top = '0px';
                        _panel.style.height = '60px';
                        _panel.style.width = '100%';
                        _panel.style.flexFlow = "row";
                        break;
                    }
                case 'bottom':
                    {
                        _panel.style.bottom = '0px';
                        _panel.style.height = '60px';
                        _panel.style.width = '100%';
                        _panel.style.flexFlow = "row";
                        break;
                    }  
                case 'left':
                    { 
                        _panel.style.left = '0px';
                        _panel.style.width = '60px';
                        _panel.style.height = '100%';
                        _panel.style.flexFlow = "column";
                        break;
                    }
                case 'right':
                default:
                    { 
                        _panel.style.right = '0px';
                        _panel.style.width = '60px';
                        _panel.style.height = '100%';
                        _panel.style.flexFlow = "column";
                        break;
                    } 
               
            }
            if(_buttons.style)
            {
                Rsd.setElStyle(_panel,_buttons.style);
            }
            li.appendChild(_panel);
            var btns = _buttons.items||[];
            for(var i in btns)
            {
                var btn = btns[i];
                var _fn = function(s,d,e){  
                    var __btn = this; 
                    me.funApplyByIOC(__btn.handler||__btn.fn,[s,e,d])
                };
                var _style = {};
                if (_buttons.position == 'top' || _buttons.position == 'button') {
                    _style = Rsd.apply({ padding: '0', lineHeight: 35, flex: 1 }, btn.style || {});
                }
                else {
                    _style = Rsd.apply({ padding: '0', lineHeight: 35 }, btn.style || {});
                }

                if (btn.handler || btn.fn) {
                    var _link_btn = Rsd.link(btn.text || '', _fn, btn, [innerCtrl, _config], _style, btn.title || btn.tip);
                    _panel.appendChild(_link_btn);
                }
                else {
                    var _lbl = Rsd.label(btn.text || '', _style, btn.title || btn.tip);
                    _panel.appendChild(_lbl);
                }
                
            }
 
        }
         //拖动对象事件
        li.setAttribute('draggable', this.itemDrag.value===true);
        
        if(me.itemDrag.value)
        { 
            //拖动图标
            {
                var _svg = document.createElementNS("http://www.w3.org/2000/svg", 'svg');
                _svg.setAttribute("id", _config.key + '_drag');
                _svg.style.color = "red";
                //_svg.style.backgroundColor="#ffffff";
                _svg.style.position = "absolute";
                _svg.style.left = "0px";
                _svg.style.height = "35px";
                _svg.style.cursor = "move";
                _svg.style.zIndex = 99;

                _svg.setAttribute("viewBox", "0 0 1024 1024");

                var _path = document.createElementNS("http://www.w3.org/2000/svg", "path");
                var _d = "M960 0v128h64V0zM832 0h64v64h-64zM704 0h64v64h-64zM576 0h64v64H576zM448 0h64v64H448zM320 0h64v64H320zM256 64V0H192v128h64zM192 192h64v64H192zM192 320h64v64H192zM256 448H192v64H0v512h512V512H256V448z m192 128v384H64V576h128v64h64V576h192z";
                _path.setAttributeNS(null, "d", _d);
                //_path.setAttributeNS(null, "fill", 'red');
                _svg.appendChild(_path);

                _path = document.createElementNS("http://www.w3.org/2000/svg", "path");
                _d = "M192 768v64h64v-128H192zM320 768h64v64H320zM576 768h64v64H576zM704 768h64v64h-64zM832 768h64v64h-64zM960 768v64h64v-128h-64zM960 576h64v64h-64zM960 448h64v64h-64zM960 320h64v64h-64zM960 192h64v64h-64z";
                _path.setAttributeNS(null, "d", _d);
                //_path.setAttributeNS(null, "fill", 'red');
                _svg.appendChild(_path);

                _path = document.createElementNS("http://www.w3.org/2000/svg", "path");
                _d = "M704 486.4c0 19.2-12.8 32-32 32s-32-12.8-32-32v-51.2l-134.4 128c-12.8 12.8-32 12.8-44.8 0-12.8-12.8-12.8-32 0-44.8l128-134.4h-51.2c-19.2 0-32-12.8-32-32s12.8-32 32-32H684.8c6.4 0 6.4 6.4 12.8 6.4 0 0 6.4 6.4 6.4 12.8V486.4z";
                _path.setAttributeNS(null, "d", _d);
                //_path.setAttributeNS(null, "fill", 'red');
                _svg.appendChild(_path);

                var _title = document.createElementNS("http://www.w3.org/2000/svg", 'title');
                _title.textContent = this.itemDrag.tip || this.itemDrag.title||"";
                _svg.appendChild(_title);
                li.appendChild(_svg);
            }

            //当开始拖动一个项目时
            Rsd.onDragStart(li, function (e) {  
                //console.log('li onDragStart',e.target,_config); 

                li.setAttribute('is_dragging',true); 
                e.dataTransfer.setData('text/plain', JSON.stringify(_config)); 
                //设置拖放操作的自定义图标。其中img_dom 设置自定义图标，x设置图标与鼠标在水平方向的距离；y设置图标与鼠标在垂直方向的距离。
                //e.dataTransfer.setDragImage(img_dom x,y); 
              
                var alt_ctrl = me.createInnerControl(_config);
                alt_ctrl.dom.id = 'alt_ctrl';
                alt_ctrl.dom.style.position = 'absolute';
                alt_ctrl.style.alignSelf = 'center';
                alt_ctrl.renderTo(li); 
                alt_ctrl.doLayout();
                alt_ctrl.loadData();
                //缩放被拖拽对象
                innerCtrl.dom.style.zIndex = 0;
                innerCtrl.dom.style.opacity=1;
                innerCtrl.dom.style.scale =0.5; 
                e.dataTransfer.setDragImage(innerCtrl.dom,220,80);

                if(me.itemDrag.onDragStart)
                { 
                    me.funApplyByIOC(me.itemDrag.onDragStart,[li,e,innerCtrl]); 
                }
            });
            //拖动中
            Rsd.onDrag(li, function (e) { 

                 //console.log('li onDrag',e.target.id);
                 li.style.transform = 'scale(0.9)';
                 //innerCtrl.setElStyle('dom',{scale:0.5});

                 if (me.itemDrag.onDrag) {
                     me.funApplyByIOC(me.itemDrag.onDrag, [li, e, innerCtrl]);
                 }

            }); 
            
            //拖动结束
            Rsd.onDragEnd(li, function (e) {
                li.setAttribute('is_dragging', false);
                li.style.transform = ''; 
                document.getElementById('alt_ctrl').remove();

                innerCtrl.dom.style.zIndex = '';
                innerCtrl.dom.style.opacity = '';
                innerCtrl.dom.style.scale ='';
                //console.log('li onDragEnd',e.target.id); 
                if (me.itemDrag.onDragEnd) {
                    me.funApplyByIOC(me.itemDrag.onDragEnd, [li, e, innerCtrl]);
                } 
            });
           
             //当鼠标移动时触发
             li.addEventListener('mousedown',function(e) { } ,{capture: true});
            //当鼠标释放时触发
            //li.onmouseup = function(e){ };
        }
        
        //以下事件为拖动过程对象事件，与拖动对象无关，所以不受是否允许拖动（属性：me.itemDrag.value）限制   
        if(me.itemDrag.target && me.itemDrag.target == 'item')
        {
            //在拖动元素进入目标元素时触发，通常用于设置拖动时的样式
            if (me.itemDrag.onDragEnter) 
            {
                Rsd.onDragEnter(li,me.id + me.itemDrag.onDragEnter, function (e) {
                    //console.log('li onDragEnter',e.target.id,li); 
                    //此事件中 不允许 获得dataTransfer数据 
                    me.funApplyByIOC(me.itemDrag.onDragEnter, [li, e]);
                });
            }
            
            //在拖动元素在目标元素上方悬停时触发，通常用于防止默认的拖放行为
            //必须注册onDragOver,否则onDrop不会触发
            Rsd.onDragOver(li, me.id + me.itemDrag.onDragOver, function (e) {
                //console.log('li onDragOver', e.target.id,li);
                if (me.itemDrag.onDragOver) {
                     //此事件中 不允许 获得dataTransfer数据 
                    me.funApplyByIOC(me.itemDrag.onDragOver, [li, e]);
                }
            });
 
            //在拖动元素离开目标元素时触发，通常用于设置拖动时的样式
            if (me.itemDrag.onDragLeave) 
            {
                Rsd.onDragLeave(li,me.id + me.itemDrag.onDragLeave, function (e) {
                    //console.log('li onDragLeave',li);
                    //此事件中 不允许 获得dataTransfer数据 
                    me.funApplyByIOC(me.itemDrag.onDragLeave, [li, e]);
                });
            }
            //在一个拖动过程中，到达目标对象释放鼠标键时触发此事件
            if (me.itemDrag.onDrop) 
            { 
                Rsd.onDrop(li,me.id + me.itemDrag.onDrop, function (e) {
                    //console.log('li onDrop', e.target.id);
                    //此事件中 可以获得dataTransfer数据 
                    me.funApplyByIOC(me.itemDrag.onDrop, [li, e,JSON.parse(e.dataTransfer.getData('text/plain')||'{}')]);
                }); 
            }
        }
        
        //点击事件
        var _click = _config.click || me.itemClick.click; 
        if (_click) {

            evtTarget.addEventListener('click',function (e) {

                if (me.selectedOnClick) {
                    if (!Rsd.isEmpty(me.itemSelectedCls)) {

                        var list = me.ctrl.element.querySelectorAll('.' + me.itemSelectedCls);
                        for (var i in list) {
                            me.removeCls(list[i], me.itemSelectedCls);
                        }

                        me.addCls(this, me.itemSelectedCls);
                        //console.log('addcls on click',me.itemSelectedCls,this);
                    }
                }
                e.preventDefault();
                //阻止后，影响子控件事件执行
                //e.stopPropagation();
                //console.trace(_click,e, _config);
                me.funApplyByIOC(_click, [innerCtrl, e,_config]);

            },true);

        }
        // 
        var _dblClick = _config.dblClick || me.itemClick.dblClick;
        if (_dblClick) {

            evtTarget.addEventListener('dblclick',function (e) {

                if (me.selectedOnDblClick) {
                    if (!Rsd.isEmpty(me.itemSelectedCls)) {
                        var list = me.ctrl.element.querySelectorAll('.' + me.itemSelectedCls);
                        for (var i in list) {
                            me.removeCls(list[i], me.itemSelectedCls);
                        }

                        me.addCls(this, me.itemSelectedCls);
                    }
                } 
                e.preventDefault();
                //阻止后，影响子控件事件执行
                //e.stopPropagation();
                me.funApplyByIOC(_dblClick, [innerCtrl, e,_config]);

            },true);
        }
        //展示勾选选择框
        if(me.showCheckbox)
        {
            var chk = document.createElement('input');
            chk.setAttribute('type','checkbox');
            //chk.style.position = "absolute";
            chk.style.top = "5px";
            chk.style.right = "5px";
            chk.style.position = "absolute";
            chk.style.zIndex = "9999"; 
            chk.value = _config.key||_config.id;
            chk.onclick = function(e){

                if (this.multiple) {
                    //支持多选 ，不处理
                }
                else {
                    //处理单选 ,清除所有已选项
                    var list = Rsd.select(me.ctrl.element, 'li>input:checked');
                    //console.log('find all checked boxs',list);
                    list.forEach(function (p) {
                        if (p != e.target) {
                            p.checked = false;
                        }
                    });
                }
                
                if(me.itemCheckedChange)
                {
                    me.funApplyByIOC(me.itemCheckedChange, [innerCtrl, e,_config]);
                }
                   
            }; 
             
            li.appendChild(chk);
        }
        //返回item对象，item.element是li dom,item.innerCtrl 是li内部子节点
        return {element:li,innerCtrl:innerCtrl,dataSource:_config};
    },

    /**
     * 创建 li 内部控件
     */
    createInnerControl:function createInnerControl(config)
    {
        //debugger;
        //console.log('config is ',config);
        var me = this;
        //li 内部 控件
        var _config = config || 'no content';

        if (Rsd.isString(_config)) {

            var _txt = document.createTextNode(_config);
            return _txt;
        }

        if (_config instanceof HTMLElement) {

            return _config;
        }

        //debugger;
        if (Rsd.isObject(_config)) {
 
            var _xtype = _config.xtype || me.itemXtype || 'label';
            //console.log('list ('+me.id+') item xtype',_xtype,_config.xtype, me.itemXtype);
            //如果 _xtype 目标控件有 其他数据属性（如：data），则需要在config中添加data属性；此处不适配 
            var ctrl = Rsd.widget(_xtype, _config);
            return ctrl; 
        }
    },
    /**
     * 
     * @returns 
     */
    getData:function getData()
    {
        return this.dataSource;
    },
     
    /**
     * 
     * @param {*} s 
     * @param {*} e 
     */
    btn_item_delete:function btn_item_delete(s,e,c)
    {
        //console.log('btn_item_delete',arguments);
        var li = e.target;
        while(li && li.tagName.toLowerCase() != 'li')
        {
            li = li.parentNode;
        }
        if(li)
        {
             li.remove(); 
        }
        //触发事件
        this.fire('afterItemDeleted',['afterItemDeleted',this,s,e,c]);
 
    },
    /**
     * 
     * @param {*} s 
     * @param {*} e 
     */
    btn_item_update:function btn_item_update(s,e,c)
    { 
        //console.log("btn_item_update",arguments);
        var li = e.target;
        while(li && li.tagName.toLowerCase() != 'li')
        {
            li = li.parentNode;
        }
         //触发事件
        this.fire('itemUpdating',['itemUpdating',this,s,e,c]);
         
    },
    /**
     * 
     * @param {*} s 
     * @param {*} e 
     * @returns 
     */
    btn_item_up:function btn_item_up(s,e,c)
    { 
        //console.log('btn_item_up',arguments);
        var li = e.target;
        while(li && li.tagName.toLowerCase() != 'li')
        {
            li = li.parentNode;
        }
        if( li && li.previousSibling)
        {
            li.parentNode.insertBefore(li, li.previousSibling); 
            this.fire('afterItemUp', ['afterItemUp', this, s, e,c]); 
            return;
        }
        alert('已在第一个位置')
    },
    /**
     * 
     * @param {*} s 
     * @param {*} e 
     * @returns 
     */
    btn_item_down:function btn_item_down(s,e,c)
    {
        //console.log('btn_item_down',arguments);
        var li = e.target;  
        while(li && li.tagName.toLowerCase() != 'li')
        {
            li = li.parentNode; 
        }
         
        if(li && li.nextSibling)
        {
             if(li.nextSibling.nextSibling)
            {
                li.parentNode.insertBefore(li,li.nextSibling.nextSibling); 
            }
            else
            {
                li.parentNode.appendChild(li);
            }
             
            this.fire('afterItemDown',['afterItemDown',this,s,e,c]);

            return;
        }
        
        alert('已在最后一个位置')
        
    }



}, function (type) {

    var _layoutGetter = function () {
        return this.__layout || {type:'hbox',align:'center'};
    };

    var _layoutSetter = function (value) {
        if(Rsd.isString(value))
        {
            this.__layout ={type:value,align:'center'}
        }
        if(Rsd.isObject(value))
        {
            this.__layout = value;
        }
        
    };
    this.defineProperty(type, "layout", _layoutGetter, _layoutSetter, false);


    var _itemsGetter = function () {

        this.__items = this.__items || [];
        return this.__items;
    };

    var _itemsSetter = function (value) {

        this.__items = value || [];
    };
    this.defineProperty(type, "items", _itemsGetter, _itemsSetter, true);

    var _itemStyleGetter = function () {

        if (!this.hasOwnProperty('__itemStyle')) {
            switch (this.layout) {
                case 'hbox':
                    this.__itemStyle = { "height": 'auto', "lineHeight": '30px' }; 
                    break;
                case 'vhox':
                    this.__itemStyle = { "height": 'auto', "lineHeight": '30px' };
                    break;
            }

        }
        return this.__itemStyle;
    };

    var _itemStyleSetter = function (value) {

        this.__itemStyle = Rsd.apply(this.itemStyle, value || {});
    };
    this.defineProperty(type, "itemStyle", _itemStyleGetter, _itemStyleSetter, true);
    //
    var _itemDragGetter = function () {

        if (!this.hasOwnProperty('__itemDrag')) {
            this.__itemDrag = { "value": false,"tip":'可拖动', "style":null  }; 
        }
        return this.__itemDrag;
    };

    var _itemDragSetter = function (value) {

        if(Rsd.isBoolean(value))
        {
            this.itemDrag.value = value;
        }
        if(Rsd.isObject(value))
        {
            this.__itemDrag = Rsd.apply(this.itemDrag, value || {}); 
        }
    };
    this.defineProperty(type, "itemDrag", _itemDragGetter, _itemDragSetter, true);
    //
    var _itemClickGetter = function () {

        if (!this.hasOwnProperty('__itemClick')) {
            this.__itemClick = { "traget": 'li',"click":null,'dblClick':null}; 
        }
        return this.__itemClick;
    }; 
    var _itemClickSetter = function (value) {

        if(Rsd.isString(value))
        {
            this.itemClick.click = value;
        }
        if(Rsd.isObject(value))
        {
            this.__itemClick = Rsd.apply(this.itemClick, value || {}); 
        }
    };
    this.defineProperty(type, "itemClick", _itemClickGetter, _itemClickSetter, true);
    //
    var _itemDblClickGetter = function () {
 
        return this.itemClick.dblClick;
    }; 
    var _itemDblClickSetter = function (value) {

        if(Rsd.isString(value))
        {
            this.itemClick.dblClick = value;
        }
         
    }; 
    this.defineProperty(type, "itemDblClick", _itemDblClickGetter, _itemDblClickSetter, true);
    //
    var _buttonsGetter = function () {

        this.__buttons = this.__buttons || null;
        return this.__buttons;
    };

    var _buttonsSetter = function (value) {

        if(Rsd.isArray(value))
        {
            this.__buttons = {position:'right',items:value};
            return;
        }
        if(Rsd.isObject(value))
        {
            this.__buttons = value;
        }
    };
    this.defineProperty(type, "buttons", _buttonsGetter, _buttonsSetter, true);
//
});
